import { type OnConnect, type Edge, type Node, ReactFlow, Position, useNodesState, useEdgesState, addEdge } from '@xyflow/react'

import { NodeTooltip, NodeTooltipContent, NodeTooltipTrigger } from './components/node-tooltip'
import { BaseNode, BaseNodeContent, BaseNodeHeader, BaseNodeHeaderTitle } from '@/components/base-node'
import { NumNode } from '@/components/nodes/num-node'
import { SumNode } from '@/components/nodes/sum-node'

import { DataEdge } from '@/components/data-edge'
import { useCallback } from 'react'

const nodeTypes = {
  num: NumNode,
  sum: SumNode,
}

const initialNodes: Node[] = [
  { id: 'a', type: 'num', data: { value: 0 }, position: { x: 0, y: 0 } },
  { id: 'b', type: 'num', data: { value: 0 }, position: { x: 0, y: 200 } },
  { id: 'c', type: 'sum', data: { value: 0 }, position: { x: 300, y: 100 } },
  { id: 'd', type: 'num', data: { value: 0 }, position: { x: 0, y: 400 } },
  { id: 'e', type: 'sum', data: { value: 0 }, position: { x: 600, y: 400 } },
]

const edgeTypes = {
  data: DataEdge,
}

const initialEdges: Edge[] = [
  {
    id: 'a->c',
    type: 'data',
    data: { key: 'value' },
    source: 'a',
    target: 'c',
    targetHandle: 'x',
  },
  {
    id: 'b->c',
    type: 'data',
    data: { key: 'value' },
    source: 'b',
    target: 'c',
    targetHandle: 'y',
  },
  {
    id: 'c->e',
    type: 'data',
    data: { key: 'value' },
    source: 'c',
    target: 'e',
    targetHandle: 'x',
  },
  {
    id: 'd->e',
    type: 'data',
    data: { key: 'value' },
    source: 'd',
    target: 'e',
    targetHandle: 'y',
  },
]

function Tooltip() {
  return (
    <NodeTooltip>
      <NodeTooltipContent position={Position.Top}>Hidden Content</NodeTooltipContent>
      <BaseNode>
        <BaseNodeContent>
          <NodeTooltipTrigger>Hover</NodeTooltipTrigger>
        </BaseNodeContent>
      </BaseNode>
    </NodeTooltip>
  )
}

const nodeTypes2 = {
  tooltip: Tooltip,
}

const initialNodes2: Node[] = [
  {
    id: '1',
    position: { x: 0, y: 0 },
    data: {},
    type: 'tooltip',
  },
]

function Flow() {
  const [nodes, , onNodesChange] = useNodesState(initialNodes2)

  return (
    <div className="h-screen w-screen p-8 bg-gray-50 rounded-xl">
      <ReactFlow nodes={nodes} nodeTypes={nodeTypes2} onNodesChange={onNodesChange} fitView />
    </div>
  )
}

export function AppOther2() {
  return <Flow />
}

export function AppBaseOther() {
  return (
    <div className="w-screen h-screen p-8">
      <BaseNode>
        <BaseNodeHeader>
          <BaseNodeHeaderTitle>Base Node</BaseNodeHeaderTitle>
        </BaseNodeHeader>
        <BaseNodeContent>This is a base node component that can be used to build other nodes.</BaseNodeContent>
      </BaseNode>
    </div>
  )
}

function AppOther() {
  const [nodes, , onNodesChange] = useNodesState(initialNodes)
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges)

  const onConnect: OnConnect = useCallback(
    (params) => {
      setEdges((edges) => addEdge({ type: 'data', data: { key: 'value' }, ...params }, edges))
    },
    [setEdges],
  )

  return (
    <div className="h-screen w-screen p-8">
      <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} nodeTypes={nodeTypes} edgeTypes={edgeTypes} fitView />
    </div>
  )
}
export default AppOther
